package com.vviton.zyhj.common.utils.alipay;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

/**
 * @Desc 支付宝通知处理类
 * @Author zhangjin
 * @Date 2015年10月30日 下午2:40:25
 */
public abstract class AlipayNotify {

    /**
     * 支付宝消息验证地址
     */
    private static final String HTTPS_VERIFY_URL = "https://mapi.alipay.com/gateway.do?service=notify_verify&";

    /**
     * @Desc 验证消息是否是支付宝发出的合法消息
     * @Author zhangjin
     * @Date 2015年10月30日 下午2:40:56
     * @param params
     *            通知返回来的参数数组
     * @return 验证结果
     */
    public static boolean verify(Map<String, String> params) {

        /* 判断responsetTxt是否为true，isSign是否为true
         * responsetTxt的结果不是true，与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
         * isSign不是true，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
         */
        String responseTxt = "true";
        if (params.get("notify_id") != null) {
            String notifyId = params.get("notify_id");
            responseTxt = verifyResponse(notifyId);
        }
        String sign = "";
        if (params.get("sign") != null) {
            sign = params.get("sign");
        }
        boolean isSign = getSignVeryfy(params, sign);

        /* 写日志记录（若要调试，请取消下面两行注释）
         * String sWord = "responseTxt=" + responseTxt + "\n isSign=" + isSign + "\n 返回回来的参数：" + AlipayCore.createLinkString(params);
         * AlipayCore.logResult(sWord);
         */

        return isSign && "true".equals(responseTxt);
    }

    /**
     * @Desc 根据反馈回来的信息，生成签名结果
     * @Author zhangjin
     * @Date 2015年10月30日 下午2:42:44
     * @param params
     *            通知返回来的参数数组
     * @param sign
     *            比对的签名结果
     * @return 生成的签名结果
     */
    private static boolean getSignVeryfy(Map<String, String> params, String sign) {
        Map<String, String> sParaNew = AlipayCore.paraFilter(params); // 过滤空值、sign与sign_type参数

        String preSignStr = AlipayCore.createLinkString(sParaNew); // 获取待签名字符串

        boolean isSign = false; // 获得签名验证结果
        if (AlipayConfig.sign_type.equals("MD5")) {
            isSign = MD5.verify(preSignStr, sign, AlipayConfig.key, AlipayConfig.input_charset);
        }
        return isSign;
    }

    /**
     * @Desc 获取远程服务器ATN结果,验证返回URL
     * @Author zhangjin
     * @Date 2015年10月30日 下午2:43:47
     * @param notifyId
     *            通知校验ID
     * @return 服务器ATN结果
     */
    private static String verifyResponse(String notifyId) {
        String partner = AlipayConfig.partner;
        String veryfyUrl = HTTPS_VERIFY_URL + "partner=" + partner + "&notify_id=" + notifyId;
        return checkUrl(veryfyUrl);
    }

    /**
     * @Desc 获取远程服务器ATN结果
     * @Author zhangjin
     * @Date 2015年10月30日 下午2:44:39
     * @param urlvalue
     *            指定URL路径地址
     * @return 服务器ATN结果 验证结果集： invalid命令参数不对 出现这个错误，请检测返回处理中partner和key是否为空 true
     *         返回正确信息 false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
     */
    private static String checkUrl(String urlvalue) {
        String inputLine = "";

        try {
            URL url = new URL(urlvalue);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            inputLine = in.readLine();
        } catch (Exception e) {
            e.printStackTrace();
            inputLine = "";
        }

        return inputLine;
    }
}
